<?php

use App\Models\Constant\Constant;
use Illuminate\Http\JsonResponse;
use Overtrue\EasySms\EasySms;
use Overtrue\EasySms\Exceptions\NoGatewayAvailableException;
use Illuminate\Support\Facades\Redis;

function responseSuccess(array $records=[],int $total=0,$msg=100000,array $appendData=[],bool $status=true,
                                array $header=[],int $code=200):JsonResponse {

    if(is_int($msg)){
        $msg = Constant::MAP_MSG[$msg]??'未知';
    }

    $data = array_merge(compact('records','total'),$appendData);
    $info = compact('data','msg','status','code');
    return response()->json($info,200,$header,JSON_UNESCAPED_UNICODE);
}

function responseFail($msg=100001,array $data=[],bool $status=false,
                             array $header=[],int $code=0):JsonResponse {
    if(is_int($msg)){
        $msg = Constant::MAP_MSG[$msg]??'未知';
    }
    $info = compact('data','msg','status','code');
    return response()->json($info,200,$header,JSON_UNESCAPED_UNICODE);
}

function makeRequest($url,array $argument = [] , $method = "GET",  $ttl = 5, $cookie='', $follow=0){

    $return = [];
    if (substr($url, 0, 7) != 'http://' && substr($url, 0, 8) != 'https://') {
        $return['result'] = 'URL is invalid';
        $return['code'] = 400;
        return $return;
    }

    if ($method == 'GET' && count($argument) > 0) {
        $url .= "?" . http_build_query($argument);
    }
    $header = [
        'Accept-Language: zh-cn,zh;q=0.8',
        'Connection: Keep-alive',
        'Cache-Control: max-age=0'
    ];

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);

    if ($method == 'POST') {
        //curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);  //验证主机
        //curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 5 );
        //curl_setopt ( $ch, CURLOPT_SAFE_UPLOAD, true );
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $argument);
    }
    if(!empty($cookie) && file_exists($cookie) ){
        curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
    }

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $ttl);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1707.0 Safari/537.36');
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);

    if( $follow==1 ){
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);//重定向
    }

    $return['result'] = curl_exec($ch);
    $return['code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return $return;
}

/**
 * 修改多维数组的value
 * @param $array
 * @param $valueEnArray 旧值
 * @param $valueZhCnArray 新值
 * @return array
 * @Date 2021/6/1
 * @Author Guodongsheng
 */
function changeValues($array, array $valueEnArray,array $valueZhCnArray):array {
    if(!is_array($array)) return $array;
    $tempArray = array();
    foreach ($array as $key=>$value){
        if(is_array($value)){
            $value = changeValues($value, $valueEnArray, $valueZhCnArray);
        }else{
            $value = array_search($value, $valueEnArray, true) === false ? $value : $valueZhCnArray[array_search($value, $valueEnArray)];
        }
        $tempArray[$key]=$value;
    }
    return $tempArray;
}

/**
 * 修改多维数组的key
 * @param $array
 * @param $keyEnArray 旧键
 * @param $keyZhCnArray 新键
 * @return array
 * @Date 2021/6/1
 * @Author Guodongsheng
 */
function changeKeys($array,array $keyEnArray,array $keyZhCnArray):array {
    if(!is_array($array)) return $array;
    $tempArray = array();
    foreach ($array as $key => $value){
        $key = array_search($key, $keyEnArray, true) === false ? $key : $keyZhCnArray[array_search($key, $keyEnArray)];
        if(is_array($value)){
            $value = changeKeys($value, $keyEnArray, $keyZhCnArray);
        }
        $tempArray[$key] = $value;
    }
    return $tempArray;
}

function checkJWT(string $token, $key = ''): array{
    $key = empty($key)?env('JWT_KEY','project'):$key;
    try {
        list($header, $payload, $signature) = explode('.', $token);
    } catch (Exception $e) {
        throw new Exception('Token无法解析。');
    }

    $payloadJson = json_decode(base64_decode($payload), true);
    if (!isset($payloadJson)) {
        throw new Exception('Token解析用户信息失败。');
    }
    if (hash_hmac('sha256', $header . '.' . $payload, md5($key)) !== $signature) {
        throw new Exception('Token签名错误。');
    }
    return $payloadJson;
}

/**
 * 随机密码
 * randomChar
 *
 * @param int $length
 * @param null $chars
 * @return false|string
 * @Date:2021/8/10
 * @Author: Rudy
 */
function randomChar(int $length = 8,$chars = null):string {
    if( empty($chars) ){
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    }
    $chars = str_shuffle($chars);
    $num = $length < strlen($chars) - 1 ? $length:str_len($chars) - 1;
    return substr($chars,0,$num);
}

/**
 * 友盟一键登录
 * oneClickLogin
 *
 * @param $token
 * @return bool|string
 * @Date:2021/8/10
 * @Author: Rudy
 */
function oneClickLogin($token){
    $mobile_token = $token;
    $host = "https://verify5.market.alicloudapi.com";
    $path = "/api/v1/mobile/info";
    $method = "POST";
    $accept = "application/json";
    $content_type = "application/json; charset=UTF-8";
    //$appKey = "203963595"; //阿里云市场购买应用的appKey
    //$appSecret = "SXl8dNv3cYAsmMxeHXOTLmP0slO7OOMD"; //阿里云市场购买应用的appSecret
    //$um_appkey = "60fac213ff4d74541c81c5ac"; //友盟的appkey
    $appKey = env('ALI_APP_KEY');
    $appSecret = env('ALI_APP_SECRET');
    $um_appkey = env('UM_APP_KEY');
    $header["Accept"] = $accept;
    $header["Content-Type"] = $content_type;
    $header["X-Ca-Version"] = "1";
    $header["X-Ca-Signature-Headers"] = "X-Ca-Key,X-Ca-Nonce,X-Ca-Stage,X-Ca-Timestamp,X-Ca-Version";
    $header["X-Ca-Stage"] = "RELEASE";
    $header["X-Ca-Key"] = $appKey; //请求的阿里云AppKey
    $header["X-Ca-Timestamp"] = strval(time() * 1000);
    mt_srand((double) microtime() * 10000);
    $uuid = strtoupper(md5(uniqid(rand(), true)));
    $header["X-Ca-Nonce"] = strval($uuid);
    //Headers
    $headers = "X-Ca-Key:" . $header["X-Ca-Key"] . "\n";
    $headers .= "X-Ca-Nonce:" . $header["X-Ca-Nonce"] . "\n";
    $headers .= "X-Ca-Stage:" . $header["X-Ca-Stage"] . "\n";
    $headers .= "X-Ca-Timestamp:" . $header["X-Ca-Timestamp"] . "\n";
    $headers .= "X-Ca-Version:" . $header["X-Ca-Version"] . "\n";
    //Url
    $url = $path . "?appkey=" . $um_appkey; //appkey为用户在友盟注册的应用分配的appKey,token和phoneNumber是app传过来的值
    //sign
    $str_sign = $method . "\n";
    $str_sign .= $accept . "\n";
    $str_sign .= "\n";
    $str_sign .= $content_type . "\n";
    $str_sign .= "\n";
    $str_sign .= $headers;
    $str_sign .= $url;
    $sign = base64_encode(hash_hmac('sha256', $str_sign, $appSecret, true)); //secret为APP的密钥
    $header['X-Ca-Signature'] = $sign;
    $post_data['token'] = $mobile_token;
    //curl
    $curl_url = $host . $path . "?appkey=" . $um_appkey; //appkey为用户在友盟注册的应用分配的appKey
    $headerArray = array();
    foreach ($header as $k => $v) {
        array_push($headerArray, $k . ":" . $v);
    }
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($curl, CURLOPT_URL, $curl_url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headerArray);
    curl_setopt($curl, CURLOPT_FAILONERROR, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_TIMEOUT, 10);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    //curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
    //curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($post_data));
    $result = curl_exec($curl);
    curl_close($curl);
    return $result;
}

//发送短信
function sendSms($phone,$template,$code) {
    //https://github.com/overtrue/easy-sms/
    $config = [
        // HTTP 请求的超时时间（秒）
        'timeout' => 5.0,
        // 默认发送配置
        'default' => [
            // 网关调用策略，默认：顺序调用
            'strategy' => \Overtrue\EasySms\Strategies\OrderStrategy::class,
            // 默认可用的发送网关
            'gateways' => [
                'aliyun',
            ],
        ],
        // 可用的网关配置
        'gateways' => [
            'errorlog' => [
                'file' => storage_path('logs/easy-sms.log'),
            ],
            'aliyun' => [
                'access_key_id' => 'LTAI5t9QZbLPxt8KjFVhkmBp',
                'access_key_secret' => 'OOjyDQhoVRk6XVyc1ys1hoSWQqxc6L',
                'sign_name' => '北京开放未来教育科技集团',
            ],
        ],
    ];

    try{
        $sms = new EasySms($config);
        $sms->send($phone,[
            //'content'  => '您的验证码为: 6379',
            'template' => $template,
            'data' => [
                'code' => $code
            ]]);
    }catch(NoGatewayAvailableException $e){

        Log::debug('getResults',$e->getResults());
        Log::debug('getExceptions',$e->getExceptions());
        //Log::debug('getException',$e->getException($gateway));
        Log::debug('getLastException',(array)$e->getLastException());
        /*
         * $e->getResults();               // 返回所有 API 的结果，结构同上
            $e->getExceptions();            // 返回所有调用异常列表
            $e->getException($gateway);     // 返回指定网关名称的异常对象
            $e->getLastException();         // 获取最后一个失败的异常对象
         * */
    }
}

function generateJWT(array $data, $key = ''):string {

    $key = empty($key)?env('JWT_KEY','project'):$key;

    $header = base64_encode(json_encode([
        'typ' => 'JWT',
        'alg' => 'HS256',
    ]));
    $payload = base64_encode(json_encode($data));
    $signature = hash_hmac('sha256', $header . '.' . $payload, md5($key));
    return $header . '.' . $payload . '.' . $signature;
}


function createNewToken(int $id,string $from):string {

    $token = generateJWT(['id'=>$id,'time'=>time()]);

    if(env('IS_USE_REDIS',false)){
        setTokenByRedis($from, $token);
    }

    return $token;
}

function setTokenByRedis($from,$token){
    $redis = Redis::connection();
    $defaultTTL = 3600 * 1;
    if(in_array($from, [Constant::FROM_GUARD])){
        $ttl = env('TOKEN_TTL_WEB',$defaultTTL);
    }elseif(in_array($from, [Constant::FROM_WEB])){
        $ttl = env('TOKEN_TTL_WEB',$defaultTTL);
    }elseif (in_array($from, [Constant::FROM_ANDROID,Constant::FROM_IOS,Constant::FROM_WX_SMALL,Constant::FROM_ZFB_SMALL])){
        $ttl = env('TOKEN_TTL_APP',$defaultTTL);
    }else{
        $ttl = env('TOKEN_TTL_WEB',$defaultTTL);
    }
    $key = "Token:$from:$token";
    $redis->setex($key,$ttl,checkJWT($token)['id']);

}

function getBrowser(){
    $brower = $_SERVER['HTTP_USER_AGENT'];
    if(preg_match('/360SE/', $brower)){
        $brower = "360se";
    }
    elseif (preg_match('/Maxthon/', $brower)){
        $brower = "Maxthon";
    }
    elseif (preg_match('/Tencent/', $brower)){
        $brower = "Tencent Brower";
    }
    elseif (preg_match('/Green/', $brower)){
        $brower = "Green Brower";
    }
    elseif (preg_match('/baidu/', $brower)){
        $brower = "baidu";
    }
    elseif (preg_match('/TheWorld/', $brower)){
        $brower = "The World";
    }
    elseif (preg_match('/MetaSr/', $brower)){
        $brower = "Sogou Brower";
    }
    elseif (preg_match('/Firefox/', $brower)){
        $brower = "Firefox";
    }
    elseif (preg_match('/MSIE\s6\.0/', $brower)){
        $brower = "IE6.0";
    }
    elseif (preg_match('/MSIE\s7\.0/', $brower)){
        $brower = "IE7.0";
    }
    elseif (preg_match('/MSIE\s8\.0/', $brower)){
        $brower = "IE8.0";
    }
    elseif (preg_match('/MSIE\s9\.0/', $brower)){
        $brower = "IE9.0";
    }
    elseif (preg_match('/Netscape/', $brower)){
        $brower = "Netscape";
    }
    elseif (preg_match('/Opera/', $brower)){
        $brower = "Opera";
    }
    elseif (preg_match('/Chrome/', $brower)){
        $brower = "Chrome";
    }
    elseif (preg_match('/Gecko/', $brower)){
        $brower = "Gecko";
    }
    elseif (preg_match('/Safari/', $brower)){
        $brower = "Safari";
    }
    else{
        $brower = "Unknow browser";
    }
    return $brower;
}

function getOS(){
    $agent = $_SERVER['HTTP_USER_AGENT'];
    if (preg_match('/Win/i', $agent) && preg_match('/nt 6.1/i', $agent)) {
        $os = 'Windows 7';
    } else if (preg_match('/Win/i', $agent) && preg_match('/nt 6.2/i', $agent)) {
        $os = 'Windows 8';
    }else if(preg_match('/Win/i', $agent) && preg_match('/nt 10.0/i', $agent)) {
        $os = 'Windows 10';#添加win10判断
    }else if (preg_match('/Win/i', $agent) && preg_match('/nt 5.1/i', $agent)) {
        $os = 'Windows XP';
    } else if (preg_match('/linux/i', $agent)) {
        $os = 'Linux';
    } else if (preg_match('/unix/i', $agent)) {
        $os = 'Unix';
    } else if (preg_match('/sun/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'SunOS';
    } else if (preg_match('/ibm/i', $agent) && preg_match('/os/i', $agent)) {
        $os = 'IBM OS/2';
    } else if (preg_match('/Mac/i', $agent) && preg_match('/PC/i', $agent))
    {
        $os = 'Macintosh';
    }
    else if (preg_match('/PowerPC/i', $agent))
    {
        $os = 'PowerPC';
    }
    else if (preg_match('/AIX/i', $agent))
    {
        $os = 'AIX';
    }
    else if (preg_match('/HPUX/i', $agent))
    {
        $os = 'HPUX';
    }
    else if (preg_match('/NetBSD/i', $agent))
    {
        $os = 'NetBSD';
    }
    else if (preg_match('/BSD/i', $agent))
    {
        $os = 'BSD';
    }
    else if (preg_match('/OSF1/i', $agent))
    {
        $os = 'OSF1';
    }
    else if (preg_match('/IRIX/i', $agent))
    {
        $os = 'IRIX';
    }
    else if (preg_match('/FreeBSD/i', $agent))
    {
        $os = 'FreeBSD';
    }
    else if (preg_match('/teleport/i', $agent))
    {
        $os = 'teleport';
    }
    else if (preg_match('/flashget/i', $agent))
    {
        $os = 'flashget';
    }
    else if (preg_match('/webzip/i', $agent))
    {
        $os = 'webzip';
    }
    else if (preg_match('/offline/i', $agent))
    {
        $os = 'offline';
    }
    else
    {
        $os = '未知操作系统';
    }
    return $os;
}

function makeWxSign($params,$KEY){
    //签名步骤一：按字典序排序数组参数
    ksort($params);
    //参数进行拼接key=value&k=v
    $array = [];
    foreach($params as $key => $value ){
        $array[] = $key.'='.$value;
    }
    $string = implode("&",$array);
    //签名步骤二：在string后加入KEY
    $string = $string . "&key=".$KEY;
    //签名步骤三：MD5加密
    $string = md5($string);
    //签名步骤四：所有字符转为大写
    $result = strtoupper($string);
    return $result;
}

